package com.mygameframework.core;

import com.mygameframework.util.Utility;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

/**
    Simple abstract class used for testing. Subclasses should
    implement the draw() method.
*/
public abstract class GameCore {

    protected static final int FONT_SIZE = 24;

    private static final DisplayMode POSSIBLE_MODES[] = {
//        new DisplayMode(1440, 900, 32, 0),
        new DisplayMode(1280, 1024, 32, 0),
        new DisplayMode(1024, 768, 32, 0),
        new DisplayMode(800, 600, 32, 0),
        new DisplayMode(800, 600, 24, 0),
        new DisplayMode(800, 600, 16, 0),
        new DisplayMode(640, 480, 32, 0),
        new DisplayMode(640, 480, 24, 0),
        new DisplayMode(640, 480, 16, 0)
    };

    protected Frame frame;
    private boolean isRunning;
    protected ScreenManager screenManager;
    protected BufferedImage offscreen;
    protected Graphics2D dbg = null;
    public ScreenManager getScreenManager() {
        ComponentColorModel d;
        return screenManager;
    }
    public static DisplayMode[] getPossible_MODES(){
        return POSSIBLE_MODES;
    }
    /**
        Signals the game loop that it's time to quit
    */
    public void stop() {
        isRunning = false;
    }

    public BufferedImage getOffscreenBufferedImage() {
        return offscreen;
    }
    public Graphics2D getOffscreenGraphics() {
        return dbg;
    }
    /**
        Calls init() and gameLoop()
    */
    public void run() {
        try {
            init();
            gameLoop();
        }
        finally {
            if(screenManager.isFullScreen())
                screenManager.restoreScreen();
        }
    }

    public Frame getFrame() {
        return frame;
    }

    public void setFrame(Frame frame) {
        this.frame = frame;
    }
    /**
     * invoked in thread's run();
        Sets full screen mode and initiates and objects.
    */
    public void init() {
        //ScreenManager 负责全屏/窗口显示
        screenManager = new ScreenManager();
        if(getFrame()!=null) screenManager.setWindow(frame);
        //TODO 全屏
//        DisplayMode displayMode =
//            screenManager.findFirstCompatibleMode(POSSIBLE_MODES);
//        screenManager.setFullScreen(displayMode);
        
        Window window = screenManager.getGameWindow();
        window.setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
        window.setBackground(Color.blue);
        window.setForeground(Color.white);
        
        if (offscreen == null) {
            //TODO offscreen是否要透明,请权计一下
            offscreen=Utility.createCompatibleImage(screenManager.getWidth()
                    ,screenManager.getHeight(),Transparency.OPAQUE);
            dbg = offscreen.createGraphics();
        }//end if
        
        isRunning = true;
    }


    public Image loadImage(String fileName) {
        return new ImageIcon(fileName).getImage();
    }


    /**
        Runs through the game loop until stop() is called.
    */
    public void gameLoop() {
        long startTime = System.currentTimeMillis();
        long currTime = startTime;
        Frame f=screenManager.getGameWindow();
        while (isRunning && frame.isVisible()) {
            if (offscreen == null) {
//                Frame f =screenManager.getFullScreenWindow();
//                if( f==null){ //非全屏
//                    f=screenManager.getGameWindow();
//                    if(!f.isVisible())f.setVisible(true);
//                }
//                offscreen = (BufferedImage) f.createImage(screenManager.getWidth(),
//                        screenManager.getHeight());
                //TODO offscreen是否要透明,请权计一下
                offscreen=Utility.createCompatibleImage(screenManager.getWidth()
                        ,screenManager.getHeight(),Transparency.OPAQUE);
                
//                System.out.println("dbimg "+offscreen.getColorModel());
//                System.out.println("dbimg "+offscreen.getColorModel().getColorSpace());
//                System.out.println("dbimg "+offscreen.getRaster());
                dbg = offscreen.createGraphics();
            }//end if
            long elapsedTime =
                System.currentTimeMillis() - currTime;
            currTime += elapsedTime;//almost equal =System.currentTimeMillis()
//            dbg=offscreen.createGraphics();
            // update
            update(elapsedTime);

            // draw the screen
            //返回的gMain可以掉失(全屏中),因为缓存策略
            Graphics2D gMain = screenManager.getGraphics();
            draw(dbg);
            gMain.drawImage(offscreen, 0, 0, null);
            gMain.dispose();
//            dbg.dispose();
            screenManager.update();//when BufferStrategy used
//            System.out.println("[GameCore.gameLoop] elapsed:"+elapsedTime);
            // take a nap
//            try {
//                Thread.sleep(20);
//            }catch (InterruptedException ex) { }
        }//end while 
//        screenManager.getFullScreenWindow().setVisible(false);
//        screenManager.getFullScreenWindow().removeNotify();
//        screenManager.getFullScreenWindow().dispose();
    }


    /** 空,有待子类实现
     * invoke currentState.execute
        Updates the state of the game/animation based on the
        amount of elapsed time that has passed.
    */
    public void update(long elapsedTime) {
        // do nothing
        
    }


    /**
     * 
     * g GameGore 里offscreen 的Graphics2D
        Draws to the screen. Subclasses must override this
        method.
    */
    public abstract void draw(Graphics2D g);
    
}
